﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "UiCommonDialogFactory.h"
#include "GmMessageBox.h"
#include "GmInputBox.h"
#include "IApplication.h"
#include "IApplicationWindow.h"
#include "IUiView.h"
#include "IUiDocumentViewManager.h"

#include "GbmpFileSystem.h"
#include "FileUtility.h"
#include "FilePath.h"

#include "IDocumentManager.h"
#include "IFileExtensions.h"
#include "IModelView.h"
#include "IDocument.h"

#include "IJournalCheckData.h"
#include "JournalUtils.h"

#include "CommandParameters.h"

#include <algorithm>

#include <QMainWindow>
#include <QColorDialog>
#include <QFileDialog>
#include <QFileInfo>
#include <QApplication>

#include "IUiManager.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;
using namespace gcmp;


namespace
{
    class QDirCurrentPathHelper
    {
    public:
        QDirCurrentPathHelper(const QString& dir)
        {
            m_backupPath = QDir::currentPath();
            QDir::setCurrent(dir);
        }

        ~QDirCurrentPathHelper()
        {
            QDir::setCurrent(m_backupPath);
        }

    private:
        QString m_backupPath;
    };

    static UiCommonDialogFactory uiFactory;
}
UiCommonDialogFactory::UiCommonDialogFactory()
{
    IUiCommonDialogFactory::m_pFactory = this;
}

UiCommonDialogFactory::~UiCommonDialogFactory()
{
    IUiCommonDialogFactory::m_pFactory = nullptr;
}

UiCommonDialog::ButtonType UiCommonDialogFactory::ShowMessage(const std::wstring& windowTitle, const std::wstring& message, int buttonTypes, bool moveToBootomRight)
{
    OwnerPtr<gcmp::IJournalCheckData> opTitleResultData = IJournalCheckData::Create();
    DBG_WARN_AND_RETURN_UNLESS(opTitleResultData, UiCommonDialog::ButtonType::Invalid, L"IJournalCheckData::Create()返回空指针",L"GDMPLab",L"2024-03-30");
    opTitleResultData->SetName(L"windowTitle");
    opTitleResultData->SetData(windowTitle.c_str(), gcmp::JournalCheckDataType::Text);
    JournalUtils::LogOrCompareCheckData(TransferOwnership(opTitleResultData));

    OwnerPtr<gcmp::IJournalCheckData> opMsgResultData = IJournalCheckData::Create();
    DBG_WARN_AND_RETURN_UNLESS(opMsgResultData, UiCommonDialog::ButtonType::Invalid, L"IJournalCheckData::Create()返回空指针",L"GDMPLab",L"2024-03-30");
    opMsgResultData->SetName(L"message");
    opMsgResultData->SetData(message.c_str(), gcmp::JournalCheckDataType::Text);
    JournalUtils::LogOrCompareCheckData(TransferOwnership(opMsgResultData));

    IApplicationWindow* pUIMainWnd = IApplication::Get()->GetApplicationWindow();
    DBG_WARN_AND_RETURN_UNLESS(pUIMainWnd, UiCommonDialog::ButtonType::Invalid, L"pUIMainWnd是空指针",L"GDMPLab",L"2024-03-30");
    QWidget* pQtMainWnd = QWidget::find((WId)pUIMainWnd->GetApplicationWindowId());
    DBG_WARN_AND_RETURN_UNLESS(pQtMainWnd, UiCommonDialog::ButtonType::Invalid, L"MainWindow是空指针",L"GDMPLab",L"2024-03-30");

    OwnerPtr<GmMessageBox> opMsgBox = NEW_AS_OWNER_PTR(GmMessageBox, pQtMainWnd);
    DBG_WARN_AND_RETURN_UNLESS(opMsgBox, UiCommonDialog::ButtonType::Invalid, L"opMsgBox是空指针",L"GDMPLab",L"2024-03-30");
    opMsgBox->SetButtonVisible(buttonTypes);
    opMsgBox->SetTitle(windowTitle);
    opMsgBox->SetMessage(message);

    if (moveToBootomRight)
    {
        opMsgBox->setFixedSize(350, 150);

        int barH = 100;
        int left = pQtMainWnd->geometry().x();
        int top = pQtMainWnd->geometry().y();
        int parentW = pQtMainWnd->geometry().width();
        int parentH = pQtMainWnd->geometry().height();
        QPoint pos = pQtMainWnd->pos();
        opMsgBox->move(left + (parentW - opMsgBox->width()), top + (parentH - barH - opMsgBox->height()));//设置左上角坐标
    }

    opMsgBox->exec();
    return opMsgBox->GetClickedButton();
}

UiCommonDialog::ButtonType UiCommonDialogFactory::ShowMiniMessageBox(const std::wstring& windowTitle, const std::wstring& message, int buttonTypes, int positionType,int width,int height)
{
    OwnerPtr<gcmp::IJournalCheckData> opTitleResultData = IJournalCheckData::Create();
    DBG_WARN_AND_RETURN_UNLESS(opTitleResultData, UiCommonDialog::ButtonType::Invalid, L"IJournalCheckData::Create()返回空指针",L"GDMPLab",L"2024-03-30");
    opTitleResultData->SetName(L"windowTitle");
    opTitleResultData->SetData(windowTitle.c_str(), gcmp::JournalCheckDataType::Text);
    JournalUtils::LogOrCompareCheckData(TransferOwnership(opTitleResultData));

    OwnerPtr<gcmp::IJournalCheckData> opMsgResultData = IJournalCheckData::Create();
    DBG_WARN_AND_RETURN_UNLESS(opMsgResultData, UiCommonDialog::ButtonType::Invalid, L"IJournalCheckData::Create()返回空指针",L"GDMPLab",L"2024-03-30");
    opMsgResultData->SetName(L"message");
    opMsgResultData->SetData(message.c_str(), gcmp::JournalCheckDataType::Text);
    JournalUtils::LogOrCompareCheckData(TransferOwnership(opMsgResultData));

    QWidget* pParentWin = QApplication::activeWindow();
    if (pParentWin == nullptr)
    {
        IApplicationWindow* pUIMainWnd = IApplication::Get()->GetApplicationWindow();
        DBG_WARN_AND_RETURN_UNLESS(pUIMainWnd, UiCommonDialog::ButtonType::Invalid, L"pUIMainWnd是空指针",L"GDMPLab",L"2024-03-30");
        pParentWin = QWidget::find((WId)pUIMainWnd->GetApplicationWindowId());
        DBG_WARN_AND_RETURN_UNLESS(pParentWin, UiCommonDialog::ButtonType::Invalid, L"MainWindow是空指针",L"GDMPLab",L"2024-03-30");
    }

    GmMessageBox msgBox(pParentWin);
    msgBox.SetButtonVisible(buttonTypes);
    msgBox.SetTitle(windowTitle);
    msgBox.SetMessage(message);

    //Set mini messagebox
    msgBox.setFixedSize(width, height);

    IUiView * pCurUIView = nullptr;
    QWidget * pCurViewWidget = nullptr;
    {
        IUiDocumentViewManager* pUiDocumentViewManager = IUiDocumentViewManager::Get();
        if (pUiDocumentViewManager)
        {
            pCurUIView = pUiDocumentViewManager->GetCurrentUiView();
            if (pCurUIView)
            {
                pCurViewWidget = QWidget::find((WId)pCurUIView->GetUiViewId());
            }
        }
    }

    if (positionType == (int)UiCommonDialog::PositionType::TopLeft)
    {
        if (pCurUIView != nullptr /*&& pStatusBar != nullptr*/)
        {
            QWidget * pCurViewWidget = QWidget::find((WId)pCurUIView->GetUiViewId());

            int leftOfCurView = pCurViewWidget->geometry().x();
            int topOfCurView = pCurViewWidget->geometry().y();
            QPoint pos = pCurViewWidget->mapToGlobal(QPoint(leftOfCurView, topOfCurView));

            msgBox.move(pos);//设置左上角坐标
        }
    }
    else if (positionType == (int)UiCommonDialog::PositionType::TopRight)
    {
        if (pCurUIView != nullptr /*&& pStatusBar != nullptr*/)
        {
            QWidget * pCurViewWidget = QWidget::find((WId)pCurUIView->GetUiViewId());

            int leftOfCurView = pCurViewWidget->geometry().x();
            int topOfCurView = pCurViewWidget->geometry().y();
            int widthOfCurView = pCurViewWidget->geometry().width();
            int heightOfCurView = pCurViewWidget->geometry().height();

            QPoint pos = pCurViewWidget->mapToGlobal(QPoint(leftOfCurView + widthOfCurView - msgBox.width(), topOfCurView));
            msgBox.move(pos);//设置右上角坐标
        }
    }
    else if (positionType == (int)UiCommonDialog::PositionType::BottomLeft)
    {
        if (pCurUIView != nullptr /*&& pStatusBar != nullptr*/)
        {
            QWidget * pCurViewWidget = QWidget::find((WId)pCurUIView->GetUiViewId());

            int leftOfCurView = pCurViewWidget->geometry().x();
            int topOfCurView = pCurViewWidget->geometry().y();
            int heightOfCurView = pCurViewWidget->geometry().height();

            QPoint pos = pCurViewWidget->mapToGlobal(QPoint(leftOfCurView, topOfCurView + heightOfCurView-msgBox.height()));
            msgBox.move(pos);//设置左下角坐标
        }
    }
    else if (positionType == (int)UiCommonDialog::PositionType::BottomRight)
    {
        if (pCurUIView != nullptr /*&& pStatusBar != nullptr*/)
        {
            QWidget * pCurViewWidget = QWidget::find((WId)pCurUIView->GetUiViewId());

            int leftOfCurView = pCurViewWidget->geometry().x();
            int topOfCurView = pCurViewWidget->geometry().y();
            int widthOfCurView = pCurViewWidget->geometry().width();
            int heightOfCurView = pCurViewWidget->geometry().height();

            QPoint pos = pCurViewWidget->mapToGlobal(QPoint(leftOfCurView + widthOfCurView - msgBox.width(), topOfCurView + heightOfCurView - msgBox.height()));
            msgBox.move(pos);//设置右下角坐标
        }
    }

    msgBox.exec();
    return msgBox.GetClickedButton();
}

int UiCommonDialogFactory::ShowMessage(const std::wstring& windowTitle, const std::wstring& message, const std::vector<ButtonSetting>& buttons,int defbutton)
{
    OwnerPtr<gcmp::IJournalCheckData> opTitleResultData = IJournalCheckData::Create();
    DBG_WARN_AND_RETURN_UNLESS(opTitleResultData, -1, L"IJournalCheckData::Create()返回空指针",L"GDMPLab",L"2024-03-30");
    opTitleResultData->SetName(L"windowTitle");
    opTitleResultData->SetData(windowTitle.c_str(), gcmp::JournalCheckDataType::Text);
    JournalUtils::LogOrCompareCheckData(TransferOwnership(opTitleResultData));

    OwnerPtr<gcmp::IJournalCheckData> opMsgResultData = IJournalCheckData::Create();
    DBG_WARN_AND_RETURN_UNLESS(opMsgResultData, -1, L"IJournalCheckData::Create()返回空指针",L"GDMPLab",L"2024-03-30");
    opMsgResultData->SetName(L"message");
    opMsgResultData->SetData(message.c_str(), gcmp::JournalCheckDataType::Text);
    JournalUtils::LogOrCompareCheckData(TransferOwnership(opMsgResultData));

    int buttonNum = (int)buttons.size();
    DBG_WARN_AND_RETURN_UNLESS(buttonNum < 7, 0, L"按钮数量要小于7个",L"GDMPLab",L"2024-03-30");

    QWidget* pParentWin = QApplication::activeWindow();
    if (pParentWin == nullptr)
    {
        IApplicationWindow* pUIMainWnd = IApplication::Get()->GetApplicationWindow();
        DBG_WARN_AND_RETURN_UNLESS(pUIMainWnd, -1, L"pUIMainWnd是空指针",L"GDMPLab",L"2024-03-30");
        pParentWin = QWidget::find((WId)pUIMainWnd->GetApplicationWindowId());
        DBG_WARN_AND_RETURN_UNLESS(pParentWin, -1, L"MainWindow是空指针",L"GDMPLab",L"2024-03-30");
    }

    GmMessageBox msgBox(pParentWin);
    msgBox.SetTitle(windowTitle);
    msgBox.SetMessage(message);

    int flags = (int)UiCommonDialog::ButtonType::Invalid;
    for(int i=0; i<buttonNum; ++i)
    {
        flags |= 1 << i;
    }
    msgBox.SetButtonVisible(flags);

    //设置按钮状态
    for(int n=0; n<buttonNum; ++n)
    {
        QPushButton* pButton = msgBox.GetButton(n);
        DBG_WARN_AND_CONTINUE_UNLESS(pButton != nullptr, L"按钮为什么不在？",L"GDMPLab",L"2024-03-30");
        pButton->setText(QString::fromStdWString(buttons[n].Name));
        pButton->setEnabled(buttons[n].IsEnable);
    }

    DBG_WARN_UNLESS(defbutton < buttonNum, L"默认按钮怎么不在范围内？",L"GDMPLab",L"2024-03-30");
    QPushButton* pCurButton = msgBox.GetButton(defbutton);
    msgBox.setFocusProxy(pCurButton);

    msgBox.exec();
    int idx = -1;
    switch(msgBox.GetClickedButton())
    {
    case UiCommonDialog::ButtonType::OK:  idx = 0; break;
    case UiCommonDialog::ButtonType::Yes: idx = 1; break;
    case UiCommonDialog::ButtonType::Cancel: idx = 2; break;
    case UiCommonDialog::ButtonType::No:  idx = 3; break;
    case UiCommonDialog::ButtonType::Ignore: idx = 4; break;
    case UiCommonDialog::ButtonType::IgnoreOnce: idx = 5; break;
    default:  idx = -1; break;
    }
    return idx;
}

int UiCommonDialogFactory::ShowMessageForCloseDocument(const std::wstring& docName, bool saveButtonStatus)
{
    std::vector<ButtonSetting> buttons;
    ButtonSetting button0 = { GBMP_TR(L"不保存"), true };
    buttons.push_back(button0);
    ButtonSetting button1 = { GBMP_TR(L"保存"), saveButtonStatus };
    buttons.push_back(button1);
    ButtonSetting button2 = { GBMP_TR(L"取消"), true };
    buttons.push_back(button2);

    //TODO: 后续zhoudc需要改进button的排列顺序（PT_FamilyEditor版本中button排序不是按照从左到右顺序排列）
    return ShowMessage(GBMP_TR(L"关闭文档"), StringUtil::FormatWString(GBMP_TR(L"是否保存对“%s”的更改？"), (docName + IDocumentManager::Get()->GetFileExtensions()->GetDefaultProjectFileExt()).c_str()), buttons, 2);
}

UiCommonDialog::ButtonType UiCommonDialogFactory::ShowInputBox(const std::wstring& windowTitle, const std::wstring& message, const std::wstring& defaultText, std::wstring& inputText)
{
    UiCommonDialog::ButtonType res = UiCommonDialog::ButtonType::Cancel;
    inputText.clear();

    OwnerPtr<gcmp::IJournalCheckData> opTitleResultData = IJournalCheckData::Create();
    DBG_WARN_AND_RETURN_UNLESS(opTitleResultData, res, L"IJournalCheckData::Create()返回空指针",L"GDMPLab",L"2024-03-30");
    opTitleResultData->SetName(L"windowTitle");
    opTitleResultData->SetData(windowTitle.c_str(), gcmp::JournalCheckDataType::Text);
    JournalUtils::LogOrCompareCheckData(TransferOwnership(opTitleResultData));

    OwnerPtr<gcmp::IJournalCheckData> opMsgResultData = IJournalCheckData::Create();
    DBG_WARN_AND_RETURN_UNLESS(opMsgResultData, res, L"IJournalCheckData::Create()返回空指针",L"GDMPLab",L"2024-03-30");
    opMsgResultData->SetName(L"message");
    opMsgResultData->SetData(message.c_str(), gcmp::JournalCheckDataType::Text);
    JournalUtils::LogOrCompareCheckData(TransferOwnership(opMsgResultData));

    QWidget* pParentWin = QApplication::activeWindow();
    if (pParentWin == nullptr)
    {
        IApplicationWindow* pUIMainWnd = IApplication::Get()->GetApplicationWindow();
        DBG_WARN_AND_RETURN_UNLESS(pUIMainWnd, res, L"pUIMainWnd是空指针",L"GDMPLab",L"2024-03-30");
        pParentWin = QWidget::find((WId)pUIMainWnd->GetApplicationWindowId());
        DBG_WARN_AND_RETURN_UNLESS(pParentWin, res, L"MainWindow是空指针",L"GDMPLab",L"2024-03-30");
    }

    GmInputBox inputBox(pParentWin, defaultText);
    inputBox.SetTitle(windowTitle);
    inputBox.SetMessage(message);
    inputBox.SetInputText(defaultText);

    if(inputBox.exec() == QDialog::Accepted)
    {
        inputText = inputBox.GetInputText();
        res = UiCommonDialog::ButtonType::OK;
    }
    return res;
}

std::wstring gcmp::UiCommonDialogFactory::ShowOpenFileDialog(const std::wstring & caption, const std::wstring & initialPath, const std::wstring & filter, int & filterIndex, bool directoryOnlyFlag, bool hasSameSuffixFlag)
{
    filterIndex = -1;
    // 如果是回放，则从脚本中获取路径
    if (JournalUtils::IsInReplay())
    {
        if (hasSameSuffixFlag)
        {
            std::wstring index = JournalUtils::GetCommandParameter(L"FilterIndex").AsWString();
            filterIndex = StringUtil::ToNumber<int>(index);
        }
        std::wstring filePath = JournalUtils::GetCommandParameter(L"FilePath").AsWString();
        filePath = LogManager::Get()->GetAbsolutePathForLog(filePath);
        return filePath;
    }

    std::wstring filePathName = L"";
    DBG_WARN_AND_RETURN_UNLESS(IApplication::Get(), filePathName ,  L"IApplication::Get() 为空",L"GDMPLab",L"2024-03-30");
    IApplicationWindow* pMainWindow = IApplication::Get()->GetApplicationWindow();
    DBG_WARN_UNLESS(pMainWindow, L"pMainWindow为空",L"GDMPLab",L"2024-03-30");

    QString qFilePathName = "";
    if (directoryOnlyFlag)
    {
        QFileDialog fileDlg;
        fileDlg.setFileMode(QFileDialog::DirectoryOnly);
        qFilePathName = fileDlg.getExistingDirectory(nullptr, QString::fromStdWString(caption));
    }
    else
    {
        QString curDir = initialPath.empty() ? QDir::currentPath() : QString::fromStdWString(initialPath);
        if (hasSameSuffixFlag)
        {
            std::vector<std::wstring> fileFilters = StringUtil::SplitString(filter, L";;");

            QString selectFilter = "";
            qFilePathName = QFileDialog::getOpenFileName(dynamic_cast<QWidget*>(pMainWindow), QString::fromStdWString(caption), curDir, QString::fromStdWString(filter), &selectFilter);
            std::vector<std::wstring>::iterator it = find(fileFilters.begin(), fileFilters.end(), selectFilter.toStdWString());
            if (it == fileFilters.end())
            {
                return filePathName;
            }
            //计算选中的filter所在下标值，从直观效果来看，从上向下的下标值依次为0-fileFilters.length()-1。
            filterIndex = static_cast<int>(&(*it) - &fileFilters[0]);
        }
        else
        {
            qFilePathName = QFileDialog::getOpenFileName(dynamic_cast<QWidget*>(pMainWindow), QString::fromStdWString(caption), curDir, QString::fromStdWString(filter));
        }

    }

    if (!qFilePathName.isNull())
    {
        filePathName = qFilePathName.toStdWString();
        QDirCurrentPathHelper(QString::fromStdWString(filePathName));
    }

    if (filePathName.empty())
    {
        // 文件名为空说明用户选择了“取消”，没有必要记录，需要终止当前命令的记录。
        JournalUtils::AbortRecordCommand();
    }
    else
    {
        // 为日志回放保存文件的相对路径
        JournalUtils::RecordCommandExtraParameter(L"FilePath", gcmp::LogManager::Get()->GetRelativePathForLog(filePathName));
        if (hasSameSuffixFlag) 
        {
            // 为日志回放保存所选中的文件过滤规则对应的index值
            JournalUtils::RecordCommandExtraParameter(L"FilterIndex", StringUtil::ToWString(filterIndex));
        }
    }

    return filePathName;
}

//std::vector<std::wstring> gcmp::UiCommonDialogFactory::ShowOpenFilesDialog(const std::wstring & caption, const std::wstring & initialPath, const std::wstring & filter)
//{
//    std::vector<std::wstring> filePathNames;
//
//    // 如果是回放，则从脚本中获取路径
//    if (JournalUtils::IsInReplay())
//    {
//        std::wstring filePathsParameter = JournalUtils::GetCommandParameter(L"FilePaths").AsWString();
//        std::vector<std::wstring> filePaths = StringUtil::SplitString(filePathsParameter, L";", true);
//        FOR_EACH(filePath, filePaths)
//        {
//            if (filePath.empty())
//            {
//                continue;
//            }
//
//            const std::wstring& absoluteFilePath = LogManager::Get()->GetAbsolutePathForLog(filePath);
//            if (!absoluteFilePath.empty())
//            {
//                filePathNames.emplace_back(absoluteFilePath);
//            }
//        }
//
//        return filePathNames;
//    }
//
//    DBG_WARN_AND_RETURN_UNLESS(IApplication::Get(), filePathNames, L"IApplication::Get() 为空", L"GDMPLab", L"2023-12-20");
//    IApplicationWindow* pMainWindow = IApplication::Get()->GetApplicationWindow();
//    DBG_WARN_UNLESS(pMainWindow, L"pMainWindow为空", L"GDMPLab", L"2023-12-20");
//
//    QStringList qFilePathNames;
//    QString curDir = initialPath.empty() ? QDir::currentPath() : QString::fromStdWString(initialPath);
//    qFilePathNames = QFileDialog::getOpenFileNames(dynamic_cast<QWidget*>(pMainWindow), QString::fromStdWString(caption), curDir, QString::fromStdWString(filter));
//
//    if (!qFilePathNames.empty())
//    {
//        int num = qFilePathNames.size();
//        for (int i = 0; i < num; ++i)
//        {
//            QString curValue = qFilePathNames.at(i);
//            std::wstring filePathName = curValue.toStdWString();
//            QDirCurrentPathHelper(QString::fromStdWString(filePathName));
//            filePathNames.emplace_back(filePathName);
//        }
//    }
//
//    if (filePathNames.empty())
//    {
//        // 文件名为空说明用户选择了“取消”，没有必要记录，需要终止当前命令的记录。
//        JournalUtils::AbortRecordCommand();
//    }
//    else
//    {
//        // 为日志回放保存文件的相对路径
//        std::wstring filePaths = L"";
//        FOR_EACH(filePathName, filePathNames)
//        {
//            std::wstring relativeFilePath = LogManager::Get()->GetRelativePathForLog(filePathName);
//            if (!relativeFilePath.empty())
//            {
//                filePaths += relativeFilePath + L";";
//            }
//        }
//        JournalUtils::RecordCommandExtraParameter(L"FilePaths", filePaths);
//    }
//
//    return filePathNames;
//}

std::wstring UiCommonDialogFactory::ShowOpenFileDialog(const std::wstring& caption, const std::wstring& initialPath, const std::wstring& filter, bool bDirOnlyFlag)
{
    int index = -1;
    return ShowOpenFileDialog(caption, initialPath, filter, index, bDirOnlyFlag,false);
}

std::wstring gcmp::UiCommonDialogFactory::ShowOpenFileDialog(const std::wstring & caption, const std::wstring & initialPath, const std::wstring & filter, int& filterIndex, bool directoryOnlyFlag)
{
    return ShowOpenFileDialog(caption, initialPath, filter, filterIndex, directoryOnlyFlag, true);
}

std::wstring UiCommonDialogFactory::ShowSaveFileDialog(const std::wstring& caption, const std::wstring& initialPath, const std::wstring& filter,const std::wstring& title)
{
    // 如果是回放，则从脚本中获取路径
    if (JournalUtils::IsInReplay())
    {
        std::wstring filePath = JournalUtils::GetCommandParameter(L"FilePath").AsWString();
        DBG_WARN_AND_RETURN_UNLESS(LogManager::Get(), filePath, L"LogManager::Get() 为空",L"GDMPLab",L"2024-03-30");
        filePath = LogManager::Get()->GetAbsolutePathForLog(filePath);
        return filePath;
    }

    std::wstring filePathName;
    IApplicationWindow* pMainWindow = IApplication::Get()->GetApplicationWindow();
    DBG_WARN_UNLESS(pMainWindow, L"pMainWindow为空",L"GDMPLab",L"2024-03-30");

    QString curDir = initialPath.empty() ? QDir::currentPath() : QString::fromStdWString(initialPath);
    OwnerPtr<QFileDialog> opFileDlg = NEW_AS_OWNER_PTR(QFileDialog, dynamic_cast<QWidget*>(pMainWindow), QString::fromStdWString(caption), curDir, QString::fromStdWString(filter));
    opFileDlg->setAcceptMode(QFileDialog::AcceptSave);
    opFileDlg->setViewMode(QFileDialog::List);
    opFileDlg->setFileMode(QFileDialog::AnyFile);
    opFileDlg->selectFile(QString::fromStdWString(title));
    if (opFileDlg->exec() == QDialog::Accepted)
    {
        QString qFilePathName = opFileDlg->selectedFiles()[0];
        if (!qFilePathName.isNull()){
            filePathName = qFilePathName.toStdWString();
            QDirCurrentPathHelper(QString::fromStdWString(filePathName));
        }
    }

    if (filePathName.empty())
    {
        // 文件名为空说明用户选择了“取消”，没有必要记录，需要终止当前命令的记录。
        JournalUtils::AbortRecordCommand();
    }
    else
    {
        // 为日志回放保存文件的相对路径
        JournalUtils::RecordCommandExtraParameter(L"FilePath", gcmp::LogManager::Get()->GetRelativePathForLog(filePathName));
    }

    return filePathName;
}

UiCommonDialog::ButtonType UiCommonDialogFactory::ShowColorSelectionDialog(const Color& init, Color& seleted)
{
    UiCommonDialog::ButtonType res = UiCommonDialog::ButtonType::Cancel;
    IApplicationWindow* pMainWindow = IApplication::Get()->GetApplicationWindow();
    DBG_WARN_UNLESS(pMainWindow, L"pMainWindow为空",L"GDMPLab",L"2024-03-30");

    QColor initQColor(
        static_cast<int>(init.GetRed()), 
        static_cast<int>(init.GetGreen()), 
        static_cast<int>(init.GetBlue()), 
        static_cast<int>(init.A)
        );

    QColor resQColor = QColorDialog::getColor(
        initQColor, 
        dynamic_cast<QWidget*>(pMainWindow), 
        QString::fromStdWString(GBMP_TR(L"请选择颜色"))
    );

    if (!resQColor.isValid())
    {
        return res;
    }

    seleted = Color(resQColor.red(), resQColor.green(), resQColor.blue(), resQColor.alpha());
    res = UiCommonDialog::ButtonType::OK;
    return res;
}